package cgs_bim

import (
	"errors"
	"cgs-server/server"
	"cgs-server/server/assets/cgs"
	"cgs-server/server/base"
	"cgs-server/server/model"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
)

type BimRepository interface {
	base.Repository

	FindByProjectId(id primitive.ObjectID) (*cgs.CgsProj, error)
	FindBySceneId(id primitive.ObjectID) (*Bim, error)
}

func NewBimRepository() BimRepository {
	return &bimRepository{
		base.RepositoryStruct{
			CollectionName: server.BimCollectionName,
		},
	}
}

type bimRepository struct {
	base.RepositoryStruct
}

func (b *bimRepository) FindBySceneId(id primitive.ObjectID) (*Bim, error) {
	db, err := server.Mongo()
	if err != nil {
		return nil, err
	}
	filter := bson.M{
		"id": id,
	}
	var result Bim
	_, err = db.FindOne(server.BimCollectionName, filter, &result)
	return &result, err
}

func (b *bimRepository) FindByProjectId(id primitive.ObjectID) (*cgs.CgsProj, error) {
	db, err := server.Mongo()
	if err != nil {
		return nil, err
	}
	filter := bson.M{
		"ID": id,
	}
	var result cgs.CgsProj
	_, err = db.FindOne(server.CgsProjectCollectionName, filter, &result)
	return &result, err
}

func (b *bimRepository) Insert(mdl *model.DataUserModel) error {
	if earth, ok := mdl.Data.(*Bim); ok {
		if err := b.CheckDB(); err != nil {
			return err
		}
		earth.ResolveEntity(earth, mdl.User)
		_, err := b.Mongo.InsertOne(b.CollectionName, earth)
		return err
	} else {
		return errors.New("Bim type error")
	}
}

func (b *bimRepository) Update(mdl *model.DataUserModel) error {
	if earth, ok := mdl.Data.(*Bim); ok {
		if err := b.CheckDB(); err != nil {
			return err
		}
		filter := bson.M{
			"id": earth.ID,
		}
		earth.ResolveFilter(earth, mdl.User, &filter)
		set := bson.M{}
		if earth.Name != "" {
			set["name"] = earth.Name
		}
		if earth.Data != nil {
			set["data"] = earth.Data
		}
		update := bson.M{
			"$set": set,
		}
		_, err := b.Mongo.UpdateOne(b.CollectionName, filter, update)
		return err
	} else {
		return errors.New("Bim type error")
	}
}

func (b *bimRepository) FindOne(mdl *model.DataUserModel) (interface{}, error) {
	if earth, ok := mdl.Data.(*Bim); ok {
		if err := b.CheckDB(); err != nil {
			return nil, err
		}
		filter := bson.M{
			"id": earth.ID,
		}
		result := &Bim{}
		find, err := b.Mongo.FindOne(b.CollectionName, filter, result)
		if find {
			return result, nil
		}
		return nil, err
	} else {
		return nil, errors.New("Bim type error")
	}
}

func (b *bimRepository) Delete(mdl *model.DataUserModel) error {
	if earth, ok := mdl.Data.(*Bim); ok {
		if err := b.CheckDB(); err != nil {
			return err
		}
		filter := bson.M{
			"id": earth.ID,
		}
		_, err := b.Mongo.DeleteOne(b.CollectionName, filter)
		return err
	} else {
		return errors.New("Bim type error")
	}
}

func (b *bimRepository) DeleteLogic(mdl *model.DataUserModel) error {
	if earth, ok := mdl.Data.(*Bim); ok {
		if err := b.CheckDB(); err != nil {
			return err
		}
		filter := bson.M{
			"id": earth.ID,
		}
		set := bson.M{}
		earth.DeleteLogic(earth, mdl.User, &set)
		update := bson.M{
			"$set": set,
		}
		_, err := b.Mongo.UpdateOne(b.CollectionName, filter, update)
		return err
	} else {
		return errors.New("Bim type error")
	}
}

